import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:dio/dio.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:im_flutter_sdk/im_flutter_sdk.dart';
import 'package:qunaimedical/im/chat/chat_page.dart';
import 'package:qunaimedical/network/http.dart';
import 'package:qunaimedical/utils/auth_util.dart';
import 'package:qunaimedical/utils/common_util.dart';
import 'package:qunaimedical/utils/dialog_util.dart';
import 'package:qunaimedical/utils/event_bus_manager.dart';
import 'package:qunaimedical/utils/log_util.dart';
import 'package:qunaimedical/utils/navigator_util.dart';
import 'package:qunaimedical/utils/sp_util.dart';
import 'package:qunaimedical/utils/toast_util.dart';
import 'package:qunaimedical/values/urls.dart';
import 'package:webview_flutter/webview_flutter.dart';

class WebPage extends StatefulWidget {
  final String url;
  final String? title;
  final WebViewCookie? webViewCookie;

  const WebPage({Key? key, required this.url, this.title, this.webViewCookie})
      : super(key: key);

  @override
  _WebPageState createState() => _WebPageState();
}

class _WebPageState extends State<WebPage> {
  final String _tag = '_WebPageState';

  WebViewController? _controller;
  late StreamSubscription _eventSubscription;

  String? _title;

  @override
  void initState() {
    super.initState();
    setState(() {
      _title = widget.title;
    });
    _eventSubscription = eventBus.on<EventBusMessage>().listen((event) {
      if (event == EventBusMessage.refreshWebpage) {
        String? newUrl = wrapUrl(widget.url);
        if (newUrl != null) {
          _controller?.loadUrl(newUrl);
        }
      }
    });
  }

  @override
  void dispose() {
    super.dispose();
    _eventSubscription.cancel();
  }

  @override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: () async {
        if (_controller != null) {
          bool canGoBack = await _controller!.canGoBack();

          final String? currentUrl = await _controller!.currentUrl();
          if (canGoBack && currentUrl != wrapUrl(widget.url)) {
            _controller!.goBack();
            return Future.value(false);
          }
        }
        return Future.value(true);
      },
      child: Scaffold(
        appBar: AppBar(
          title: Text(_title ?? ""),
          elevation: 0,
          actions: [
            GestureDetector(
              child: Container(
                margin: EdgeInsets.only(right: 8),
                child: Icon(Icons.home,size: 30),
              ),
              onTap: () {
                String? newUrl = wrapUrl(widget.url);
                if (newUrl != null) {
                  _controller?.loadUrl(newUrl);
                }
              },
            ),
          ],
        ),
        body: WebView(
          initialUrl: wrapUrl(widget.url),
          javascriptMode: JavascriptMode.unrestricted,
          zoomEnabled: false,
          initialCookies:
              widget.webViewCookie == null ? [] : [widget.webViewCookie!],
          onPageStarted: (url) {
            if (url.startsWith("https://meeting")) {
              CommonUtil.launchInBrowser(url);
              Navigator.pop(context);
            }
            if (url.contains("qalive.belovedlive.com")) {
              CommonUtil.launchInBrowser(url);
            }
          },
          onWebViewCreated: (WebViewController controller) async {
            _controller = controller;
          },
          onPageFinished: (url) async {
            String? title = await _controller?.getTitle();
            if (title != null) {
              setState(() {
                _title = title;
              });
            }
          },
          javascriptChannels: Set.from([
            JavascriptChannel(
              name: 'doctorDetail',
              onMessageReceived: (JavascriptMessage message) async {
                Log.d(_tag, "data from doctorDetailPage: ${message.message}");
                Map<String, dynamic> data = json.decode(message.message);
                EMConversation? conv = await EMClient.getInstance.chatManager
                    .getConversation(data["id"]);
                conv?.setExt({"id": data["id"], "name": data["toName"]});
                if (conv != null) {
                  navigateTo(context, ChatPage(conv));
                }
              },
            ),
            JavascriptChannel(
              name: 'autoLogin',
              onMessageReceived: (JavascriptMessage message) async {
                Log.d(_tag, "data from autoLogin: ${message.message}");
                Map<String, dynamic> data = json.decode(message.message);
                var value = data["state"];
                if (value == "meet") {
                  eventBus.fire(EventBusMessage.jump2ConsultationCenter);
                }
                if (value == "me") {
                  eventBus.fire(EventBusMessage.jump2Me);
                }
                Navigator.pop(context);
              },
            ),
            JavascriptChannel(
              name: 'fileUpdate',
              onMessageReceived: (JavascriptMessage message) async {
                Log.d(_tag, "data from fileUpdate: ${message.message}");
                Map<String, dynamic> data = json.decode(message.message);
                // 2022.11.23 mod lyy file upload
                if (data["appointmentId"] != null) {
                  _flutterUploadFile(data);
                }
              },
            ),
            JavascriptChannel(
              name: 'MeetBridge',
              onMessageReceived: (JavascriptMessage message) async {
                Log.d(_tag, "data from MeetBridge: ${message.message}");
                Map<String, dynamic> data = json.decode(message.message);
                if (data["appClipBoardValue"] != null) {
                  Clipboard.setData(
                      ClipboardData(text: data["appClipBoardValue"]));
                  ToastUtil.show("已复制到剪贴板");
                }
              },
            ),
          ]),
        ),
      ),
    );
  }

  String? wrapUrl(String? url) {
    if (url != null && url.contains(Urls.DOMAIN)) {
      url +=
          "${url.contains("?") ? "&" : "?"}from=app&operatingSystem=${Platform.operatingSystem}";
      if (AuthUtil.isLogin()) {
        url +=
            "&autoTest=autoLogin&userName=${SPUtil.getUserName()}&password=${SPUtil.getPassword()}";
      }
    }
    Log.d(_tag, "open url: $url");
    return url;
  }

  // 2022.11.23 mod lyy file upload
  void _flutterUploadFile(Map<String, dynamic> data) async {
    FilePickerResult? result = await FilePicker.platform.pickFiles();
    if (result != null) {
      FormData formData = FormData.fromMap({
        "appointmentId": data["appointmentId"],
        "file": await MultipartFile.fromFile(result.files.single.path!),
        "userId": SPUtil.getQAUser()?.id,
        "passWord": SPUtil.getPassword(),
      });

      try {
        DialogUtil.showWaitDialog(context);
        var response =
            await XHttp.instance.post(Urls.UPLOAD_FILE, data: formData);
        if (mounted) {
          Navigator.pop(context);
          if (response.statusCode == 200 && response.data["code"] == 1) {
            _controller?.runJavascript("linkFlutter()");
          }
        }
      } on DioError catch (e) {
        if (mounted) {
          Navigator.pop(context);
          CommonUtil.catchDioError(e);
        }
      }
    } else {
      // User canceled the picker
    }
  }
}
